/**
 * @class   wosh::Notification
 * @brief   A special Event message containing text or information for user(s).
 *
 *
 *
 ****************************************************************************
 * @version 0.8.499 $Id: Notification.h 2863 2010-08-07 04:28:58Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_Notification_H__
 #define __WOSH_Core_Notification_H__

 #include <woshDefs.h>
 #include <core/MessageContent.h>
 #include <core/URI.h>



namespace wosh {

 template <class T> class DataFieldCollector;

class Notification : public MessageContent
 {
	WOSH_SERIALIZABLE_ABSTRACT(wosh::Notification)

	public:
		/// priority of the notification
		enum PRIORITY {
			PRIORITY_UNKNOWN	= 0x00,
			PRIORITY_LOW		= 0x01,
			PRIORITY_DEFAULT	= 0x02,
			PRIORITY_HIGH		= 0x04,
			PRIORITY_REALTIME	= 0x08
		};

		/// type of the notification
		enum TYPE {
			TYPE_UNKNOWN	= 0x00,
			TYPE_TEXTUAL	= 0x01,
			TYPE_AUDIO		= 0x02,
			TYPE_IMAGE		= 0x04,
			TYPE_VIDEO		= 0x08,
			TYPE_DATA		= 0x10 // =16
		};

		enum PROTOCOL {
			PROTOCOL_UNKNOWN	= 0x00,
			PROTOCOL_SHELL		= 0x01,
			PROTOCOL_HUMAN		= 0x02
		};

	public:
		/**
		 * @brief  Empty constructor.
		 */
		Notification();
		/**
		 * @brief  Copy constructor.
		 * @param m [in] the source object to be copied
		 */
		Notification( const Notification& m );
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~Notification() { }


	public:
		virtual const std::string& getPlain() const = 0;
		virtual void setPlain( const std::string& value ) = 0;

//@}
/** @name Getters
 * @{
 ******************************************************************************/
	public:
		inline long getID() const								{ return this->uid; }
		inline long getFlowID() const							{ return this->flow_uid; }

		inline long getTimeStamp() const						{ return this->timestamp; }
		std::string getTimeStampUTF() const;

		inline long getSentTimeStamp() const					{ return this->sent_timestamp; }
		inline long getReadTimeStamp() const					{ return this->read_timestamp; }

		inline bool isSent() const								{ return ( this->sent_timestamp > 0 ); }
		inline bool isRead() const								{ return ( this->read_timestamp > 0 ); }

		inline const std::string& getSender_ID() const			{ return this->sender_id; }
		inline std::string& getSender_ID()						{ return this->sender_id; }
		inline const std::string& getSender_User() const		{ return this->sender_user; }
		inline std::string& getSender_User()					{ return this->sender_user; }

		inline const std::string& getRecipent_ID() const		{ return this->recipent_id; }
		inline std::string& getRecipent_ID()					{ return this->recipent_id; }
		inline const std::string& getRecipent_User() const		{ return this->recipent_user; }
		inline std::string& getRecipent_User()					{ return this->recipent_user; }

		inline const std::string& getRecipent_Group() const		{ return this->recipent_group; }
		inline std::string& getRecipent_Group()					{ return this->recipent_group; }

		inline bool isForAnyone() const							{ return ((this->recipent_user == "") && (this->recipent_group == "")); }

		inline const std::string& getLanguage() const			{ return this->language; }
		inline std::string& getLanguage()						{ return this->language; }

		inline Notification::PROTOCOL getProtocol() const		{ return this->protocol; }
		inline const char* getProtocolAsString() const			{ return getProtocolAsString(this->protocol); }

		inline const URI& getPreferredCommunicator() const { return this->preferredComm; }
		inline URI& getPreferredCommunicator()			{ return this->preferredComm; }


		virtual inline MessageContent::TYPE getType() const		{ return MessageContent::NOTIFICATION; }

		virtual Notification::TYPE getNotificationType() const = 0;

		inline const char* getNotificationTypeAsString() const	{ return getNotificationTypeAsString(getNotificationType()); }

		inline Notification::PRIORITY getPriority() const		{ return this->priority; }
		inline const char* getPriorityAsString() const			{ return getPriorityAsString(this->priority); }

		static const char* getPriorityAsString( Notification::PRIORITY priority );
		static const char* getProtocolAsString( Notification::PROTOCOL protocol );
		static const char* getNotificationTypeAsString( Notification::TYPE type );

		static DataFieldCollector<Notification>* getDataFields();

//@}
/** @name Setters
 * @{
 ******************************************************************************/
	public:
		inline void setFlowID( long uid )							{ this->flow_uid = uid; }

		inline void setSender_ID( const std::string& value )		{ this->sender_id = value; }
		inline void setSender_User( const std::string& value )		{ this->sender_user = value; }

		inline void setRecipent_ID( const std::string& value )		{ this->recipent_id = value; }
		inline void setRecipent_User( const std::string& value )	{ this->recipent_user = value; }

		inline void setRecipent_Group( const std::string& value )	{ this->recipent_group = value; }

		inline void setLanguage( const std::string& value ) 		{ this->language = value; }

		inline void setProtocol( Notification::PROTOCOL proto )		{ this->protocol = proto; }

		void setTimeStamp();
		inline void setTimeStamp( long value )						{ this->timestamp = value; }

		void setRead( bool value, long epoch = 0 );

		void setSent( bool value, long epoch = 0 );

		inline void setPriority( Notification::PRIORITY prior )		{ this->priority = prior; }
	
		inline void setPreferredCommunicator( const URI& uri )		{ this->preferredComm = uri; }


//@}
/** @name Operators Overloading
 * @{
 ******************************************************************************/
	public:
		virtual Notification& operator=(const Notification& m);
		virtual bool operator==(const Notification &other) const;
		virtual bool operator!=(const Notification &other) const { return !(*this == other);  }
//@}
/** @name Serialization interface
 * @{
 ******************************************************************************/
	public:
		virtual std::string toString() const;
		virtual bool updateHash( DataHashContext* hash_context ) const;
		virtual int compare( const ISerializable* other ) const;
//@}
	protected:
		virtual void clear();

	protected:
		long uid;					///<
		long flow_uid;				///<
		long timestamp;				///< timestamp (epoch) of the notification

		Notification::PRIORITY priority; ///< priority of the notification

		std::string sender_id;		///< phone_number/account SENDING message
		std::string sender_user;	///< associated WOSH user (sender_id)

		std::string recipent_id;	///< phone_number/account RECEIVING message
		std::string recipent_user;	///< associated WOSH user (recipent_id)
		std::string recipent_group;	///< associated WOSH group (not used actually)

		long read_timestamp;		///<
		long sent_timestamp;		///<

		Notification::PROTOCOL protocol;	///<
		std::string language; // it_IT

		URI preferredComm;


}; // class def

}; // namespace wosh

#endif //__WOSH_Core_Notification_H__
